/**
 * This program prints a wind chill table for given temperatures and
 * wind speeds.
 */

import java.text.DecimalFormat;

class WindChill
{
    public static void main (String[] args)
    {
        // DECLARE VARIABLES/DATA DICTIONARY 

        double[] tempArray;     // An array of Celsius temperatures
        int nt;                 // Length of tempArray
        double[] speedArray;    // An array of wind speeds in km/hr
                                //         must be at least 5.0 km/hr
        int ns;                 // Length of speedArray
        double[][] chillTable;  // A matrix of wind chill values

        // PRINT OUT IDENTIFICATION INFORMATION
        
        System.out.println();
        System.out.println("ITI 1120 Fall 2006, Lab 9, Exercise 1");
        System.out.println("Name: Diana Inkpen, Student# 123456");
        System.out.println();


        // READ IN GIVENS
     
        System.out.println( "Enter a set of temperatures between -50 and +5:  " );
        tempArray = ITI1120.readDoubleLine( );
        nt = tempArray.length;
        
        System.out.println( );
        System.out.println( "Enter a set of wind speeds >= 5.0:  ");
        speedArray = ITI1120.readDoubleLine( );
        ns = speedArray.length;

        // BODY OF ALGORITHM
     
        chillTable = createWindChillTable( tempArray, nt, speedArray, ns );

        // PRINT OUT RESULTS AND MODIFIEDS

        printTable ( tempArray, speedArray, chillTable );

    }

    // If the 'main' method calls other algorithms, put the method(s) below.

    /**
     * Create a wind chill matrix for a set of given temperatures
     * and wind speeds.
     * 
     * 
     * GIVENS:  tempArray:  an array of doubles containing temperature values
     *          nt:         the length of 'tempArray'
     *          speedArray: an array of doubles containing wind speed values
     *                      ( each value must be >= 5.0 )
     *          ns:         the length of 'speedArray'
     */

    public static double[][] createWindChillTable( double[] tempArray, int nt,
                                                   double[] speedArray, int ns )
    {
        // DECLARE VARIABLES/DATA DICTIONARY 

        int t;                  // INTERMEDIATE:  index into temperature array
        int s;                  // INTERMEDIATE:  index into wind speed array
        double[][] chillTable;  // RESULT:        wind chill matrix

        // BODY OF ALGORITHM
     
        // Create array of rows
        
        chillTable = new double[nt][];

        // Outer loop:  go through temperature array
        
        t = 0;
        while ( t < nt )
        {
            // For each row, create an array to hold the values in each row
            
            chillTable[t] = new double[ns];

            // Inner loop:  go through speed array
            
            s = 0;
            while ( s < ns )
            {
                // Use temperature and speed values to determine one
                // entry in the matrix
                
                chillTable[t][s] = windChill( tempArray[t], speedArray[s] );
                    
                s = s + 1;
            }
            t = t + 1;
        }

        // RETURN RESULT

        return chillTable;
    }

    /**
     * Determine the wind chill for a given temperature and
     * wind speed.  The wind speed must be at least 5 km/hr.
     * 
     * [Source for formula:  Environment Canada]
     * 
     * GIVENS:  temperature:  a temperature in degrees Celsius (between -50.0
     *                        and 5.0)
     *           windSpeed:    a wind speed in kilometres/hour (must be >= 5.0)
     */

    public static double windChill( double temperature, double windSpeed )
    {
        double chill;
        double vFactor;

        vFactor = Math.pow( windSpeed, 0.16 );
        chill = 13.12 + 0.6215 * temperature - 11.37 * vFactor +
                0.3965 * temperature * vFactor;

        return chill;
    }

    /**
     * Print a wind chill matrix with nice formatting and column
     * and row headings.
     * <p>
     * Note the 3 arrays that are GIVENS; the lengths
     * are determined from the arrays themselves.  The temperature and
     * wind speed arrays are needed only for the column and row headings;
     * the table entries come from 'chillTable'.
     */
    
    public static void printTable( double[] tempArray, double[] speedArray,
                                   double[][] chillTable )
    {
        int nt;     // size of temperature array (tempArray)
        int ns;     // size of wind speed array (speedArray)
        int t;      // temperature (row) index
        int s;      // speed (column) index

        nt = tempArray.length;
        ns = speedArray.length;

        // Print title
        
        System.out.println( );
        System.out.println( "Wind Chill Table" );
        System.out.println( );

        // Print heading for columns
        
        System.out.print( "Speed:  " );
        for ( s = 0; s < ns; s = s + 1 )
        {
            System.out.print( format( speedArray[s] ) + " " );
        }
        System.out.println( );

        // Print a heading separator line
        
        System.out.print( "--------" );
        for ( s = 0; s < ns; s = s + 1 )
        {
            System.out.print( "------" );
        }

        System.out.println( );
        System.out.println( "Temp. |" );

        // For each row, print a row heading, and then loop through
        // the matrix entries to print them.  The values of type
        // double are formatted using method format( ) below.
        
        for ( t = 0; t < nt; t = t + 1 )
        {
            // Print row heading
            
            System.out.print( format( tempArray[t] ) + " | " ); 
            
            // Print entries in row
            
            for ( s = 0; s < ns; s = s + 1 )
            {
                System.out.print( format( chillTable[t][s] ) + " " );
            }
            System.out.println( );
        }        
    }

    /**
     * Reformats double values as Strings with length 5 and one
     * decimal place.
     * <p>
     * This will set up printing a matrix with columns that line up.
     */
     
    public static String format( double value )
    {
        String result;
        DecimalFormat df;
        int numBlanks;

        // The following requests numeric output with exactly one decimal
        // place, and at least one but no more than two digits to the left
        // of the decimal point.  See java.text.DecimalFormat.
        
        df = new DecimalFormat( "#0.0" );

        // The next line actually does the formatting, and produces a String.
        
        result = df.format( value );

        // The following makes sure that the String has exactly 5 characters
        // (needed to space columns evenly) and adds blanks to the front if
        // needed.  Class DecimalFormat ought to do this, but...
        
        numBlanks = 5 - result.length( );
        for ( int index = 1; index <= numBlanks; index++ )
        {
            result = " " + result;
        }
        
        return result;
    }
}
